package com.alibaba.cirtus.ots.application.adapter.ability.facade.serviceV2.dp.mndataif006;

import com.alibaba.cirtus.ots.application.adapter.ability.model.enums.EmployeeStatusEnum;
import com.alibaba.citrus.ots.common.annotation.FacadeInvoker;
import com.alibaba.citrus.ots.common.lock.RedisLock;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.cz.base.tool.message.ErrorMessage;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcorder.model.dto.AccountDeactivationRequest;
import com.epoch.app.bcorder.model.dto.AccountDeactivationResponse;
import com.epoch.app.bcorder.model.dto.BaselineGetEmployeeByWorkIdRequest;
import com.epoch.app.bcorder.model.dto.BaselineGetEmployeesEs2Request;
import com.epoch.app.bcorder.model.dto.EmployeeGetCurrentLoginResponse;
import com.epoch.app.bcorder.model.dto.EmployeeSDO;
import com.epoch.app.bcorder.service.BaseDataService;
import com.epoch.app.bcorder.service.BcOrderService;
import com.epoch.app.bcots.contants.BcOtsConstants;
import com.epoch.app.crplatformenhance.model.dto.UpdateEmployeeRequest;
import com.epoch.app.crplatformenhance.service.CrPlatformEnhanceService;
import com.epoch.app.otsapplicationadaptersdk.dp.EmployeeInfoSDO;
import com.epoch.app.otsapplicationadaptersdk.dp.MnDataEmployeeInfo;
import com.epoch.app.otsapplicationadaptersdk.dp.MnDataUpdateEmployeeInfoRequest;
import com.epoch.app.otsapplicationadaptersdk.dp.mndataif006.dto.UpdateRequest;
import com.epoch.app.otsapplicationadaptersdk.dp.mndataif006.service.MnDataIf006Service;
import com.epoch.app.otsapplicationadaptersdk.model.dto.MnDataUpdateEmployeeInfoResponse;
import com.epoch.app.otsapplicationadaptersdk.model.dto.RestDpPersonDataRequest;
import com.epoch.app.otsapplicationadaptersdk.model.dto.RestDpPersonDataResponse;
import com.epoch.app.otsapplicationadaptersdk.service.DpService;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.logging.log4j.util.Strings;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * TODO need 确认下这个接口干嘛的？命名是更新，但是实际上就是做了查询，而且也没有将查询结果返回了下。。。
 *
 * @author wangyundan
 * @description:
 * @date 2021/12/21
 */
@Component
public class MnDataIf006V2ServiceImpl implements MnDataIf006Service {
    private final Log log = Log.getLogger(MnDataIf006V2ServiceImpl.class);

    @Resource
    private DpService dpService;

    @Resource
    private BcOrderService bcOrderService;

    @Resource
    private CrPlatformEnhanceService crPlatformEnhanceService;

    @Resource
    private BaseDataService baseDataService;

    private static final String lockKey = "updateEmployeeInfo";

    private static final int ZERO = 0;

    private static final int firstPage = 1;

    private static final int size = 1000;

    @Override
    @FacadeInvoker
    public Result<MnDataUpdateEmployeeInfoResponse> updateEmployeeInfo(MnDataUpdateEmployeeInfoRequest mnDataUpdateEmployeeInfoRequest) {
        log.info("MnDataIf006:updateEmployeeInfo" + JSONObject.toJSONString(mnDataUpdateEmployeeInfoRequest));
        List<String> workIdList = Lists.newArrayList();
        MnDataUpdateEmployeeInfoResponse emptyResponse = MnDataUpdateEmployeeInfoResponse.builder().workIds(workIdList).build();
        RestDpPersonDataRequest request = new RestDpPersonDataRequest();
        request.setPageNum("1");
        request.setPageSize("10");
        StringBuilder key = new StringBuilder(lockKey);
        if (mnDataUpdateEmployeeInfoRequest != null && Strings.isNotBlank(mnDataUpdateEmployeeInfoRequest.getDs())) {
            request.setDs(mnDataUpdateEmployeeInfoRequest.getDs());
            key.append(mnDataUpdateEmployeeInfoRequest.getDs());
        } else {
            key.append("All");
        }
        log.info("lockKey:" + key);
        try (RedisLock lock = new RedisLock(BcOtsConstants.REDIS_CACHE_CODE(), key.toString())) {
            boolean locked = lock.lock();
            if (!locked) {
                log.error("updateEmployeeInfo获取锁失败");
                return Result.fail("OTS-02-007-00-16-001", "员工状态正在更新中，请稍后重试");
            }
            EmployeeGetCurrentLoginResponse employeeGetCurrentLoginResponse = bcOrderService.employeeGetCurrentLogin();
            String employeeId = employeeGetCurrentLoginResponse.getEmployeeId();
            log.info("MnDataIf006:" + "employeeId1:" + employeeId);
            if (Strings.isBlank(employeeId)) {
                return Result.success(null, "OTS-01-001-01-15-016", ErrorMessage.code("OTS-01-001-01-15-016", null).getDisplayErrorMessage());
            }

            StopWatch stopWatch = new StopWatch("MnDataIf006ServiceImpl.updateEmployeeInfo");
            stopWatch.start();
            //获取客户员工
            List<String> employeeInfoList = Lists.newArrayList();

            RestDpPersonDataResponse restDpPersonDataResponse = null;
            try {
                restDpPersonDataResponse = dpService.restDpPersonData(request);
            } catch (Exception e) {
                log.error("MnData_rest_req_occur_exception,restDpPersonData_errorMsg={}",e.getMessage());
                throw e;
            }

            MnDataEmployeeInfo result = restDpPersonDataResponse.getResult();
            if (!restDpPersonDataResponse.getSuccess() || result == null) {
                return Result.success(null, "OTS-01-001-01-15-017", ErrorMessage.code("OTS-01-001-01-15-017", null).getDisplayErrorMessage());
            }
            Long totalNum = result.getTotalNum();
            log.info("MnDataIf006:" + "客户员工总个数:" + totalNum);
            if (totalNum == ZERO || CollectionUtils.isEmpty(result.getRows())) {
                log.info("MnDataIf006:获取客户员工数据为空");
                return Result.success(emptyResponse);
            }
            List<EmployeeInfoSDO> EmployeeInfoList = getEmployeeInfoSDOS(request, totalNum);
            employeeInfoList = EmployeeInfoList.stream().filter(employeeInfoSDO -> employeeInfoSDO.getEmplid() != null
                            && employeeInfoSDO.getHrstatus() != null
                            && employeeInfoSDO.getHrstatus().equals(EmployeeStatusEnum.INVALID.getValue()))
                    .map(EmployeeInfoSDO::getEmplid)
                    .collect(Collectors.toList());
            log.info("MnDataIf006:" + "无效账号employeeInfoList:" + employeeInfoList.size());

            //获取平台员工
            Map<String, Integer> platformEmployeeMap = Maps.newHashMap();
            Result<List<EmployeeSDO>> listResult = baseDataService.baselineGetEmployeesEs2(BaselineGetEmployeesEs2Request.builder().status(1).build());
            List<EmployeeSDO> platformEmployeeList = listResult.getResult();
            int total = listResult.getTotal();
            log.info("MnDataIf006:" + "平台员工总个数:" + total);
            if (!listResult.isSuccess() || CollectionUtils.isEmpty(platformEmployeeList) || total == ZERO) {
                log.info("MnDataIf006:获取平台员工数据为空");
                return Result.success(emptyResponse);
            }
            platformEmployeeList = getPlatformEmployeeList(total);
            EmployeeSDO employee = platformEmployeeList.stream().filter(employeeSDO -> employeeSDO.getWorkId() != null)
                    .findAny().orElse(null);
            if (employee != null) {
                platformEmployeeMap = platformEmployeeList.stream().filter(employeeSDO -> employeeSDO.getWorkId() != null)
                        .collect(Collectors.toMap(EmployeeSDO::getWorkId, EmployeeSDO::getStatus, (a, b) -> a));
            }

            //过滤在平台有账号的员工
            if (MapUtils.isNotEmpty(platformEmployeeMap)) {
                workIdList = employeeInfoList.stream().filter(platformEmployeeMap::containsKey).collect(Collectors.toList());
            }

            log.info("MnDataIf006:需要更新的员工工号" + JSONObject.toJSONString(workIdList));
            log.info("MnDataIf006:需要更新的员工数量" + workIdList.size());

            stopWatch.stop();
            log.info("MnDataIf006:" + "获取数据耗时:" + stopWatch.getTotalTimeMillis() + "ms");
            return Result.success(MnDataUpdateEmployeeInfoResponse.builder().workIds(workIdList).build());
        } catch (Exception e) {
            log.info("MnDataIf006_updateEmployeeInfo_error ",e);
            return Result.fail(null, "OTS-01-001-01-15-017", ErrorMessage.code("OTS-01-001-01-15-017", null).getDisplayErrorMessage());
        }
    }

    @NotNull
    private List<EmployeeSDO> getPlatformEmployeeList(int total) {
        List<EmployeeSDO> platformEmployeeList;
        int pageTotal = total % size == ZERO ? total / size : total / size + 1;
        platformEmployeeList = Lists.newArrayList();
        for (int i = 0; i < pageTotal; i++) {
            Result<List<EmployeeSDO>> result = baseDataService.baselineGetEmployeesEs2(BaselineGetEmployeesEs2Request.builder()
                    .status(1).start(i * size).limit(size).build());
            List<EmployeeSDO> list = result.getResult();
            if (!result.isSuccess() || CollectionUtils.isEmpty(list)) {
                continue;
            }
            platformEmployeeList.addAll(list);
        }
        log.info("MnDataIf006:获取平台员工数量:" + JSONObject.toJSONString(platformEmployeeList.size()));
        return platformEmployeeList;
    }

    @NotNull
    private List<EmployeeInfoSDO> getEmployeeInfoSDOS(RestDpPersonDataRequest request, Long totalNum) {
        Integer pageNum = firstPage;
        Long pageSize = 2000L;
        long pageTotal = totalNum % pageSize == ZERO ? totalNum / pageSize : totalNum / pageSize + 1;
        long newSize;
        List<EmployeeInfoSDO> list = Lists.newArrayList();
        while (pageNum <= pageTotal && list.size() < totalNum) {
            request.setPageNum(String.valueOf(pageNum));
            request.setPageSize(String.valueOf(pageSize));
            RestDpPersonDataResponse response = dpService.restDpPersonData(request);
            pageNum++;
            MnDataEmployeeInfo mnDataEmployeeInfo = response.getResult();
            if (!response.getSuccess() || mnDataEmployeeInfo == null) {
                continue;
            }
            //判断pageSize是否改变
            newSize = mnDataEmployeeInfo.getPageSize().longValue();
            if (newSize == ZERO) {
                break;
            }
            if (pageSize != newSize) {
                pageSize = newSize;
                //重置page数据并重新循环
                pageNum = firstPage;
                totalNum = mnDataEmployeeInfo.getTotalNum();
                pageTotal = totalNum % pageSize == 0 ? totalNum / pageSize : totalNum / pageSize + 1;
            }
            List<EmployeeInfoSDO> rows = mnDataEmployeeInfo.getRows();
            if (CollectionUtils.isEmpty(rows)) {
                continue;
            }
            list.addAll(rows);
        }
        log.info("MnDataIf006:获取客户员工数量:" + JSONObject.toJSONString(list.size()));
        return list;
    }

    @Override
    @FacadeInvoker
    public Result<Boolean> update(UpdateRequest updateRequest) {
        try {
            if (updateRequest == null) {
                return Result.success(false);
            }
            String workId = updateRequest.getWorkId();
            log.info("update开始:工号为" + workId);
            if (workId == null) {
                return Result.success(false);
            }
            EmployeeGetCurrentLoginResponse employeeGetCurrentLoginResponse = bcOrderService.employeeGetCurrentLogin();
            String employeeId = employeeGetCurrentLoginResponse.getEmployeeId();
            log.info("MnDataIf006:" + "employeeId2:" + employeeId);
            if (Strings.isBlank(employeeId)) {
                return Result.success(false, "OTS-01-001-01-15-016", ErrorMessage.code("OTS-01-001-01-15-016", null).getDisplayErrorMessage());
            }
            //查询员工
            Result<EmployeeSDO> employeeResult = baseDataService.baselineGetEmployeeByWorkId(BaselineGetEmployeeByWorkIdRequest.builder()
                    .workId(workId).status(1).build());
            EmployeeSDO employeeSDO = employeeResult.getResult();
            if (!employeeResult.isSuccess() || employeeSDO == null) {
                log.info("MnDataIf006:未找到工号为" + workId + "的员工");
                return Result.success(false, "OTS-01-001-01-15-018", ErrorMessage.code("OTS-01-001-01-15-018", null).getDisplayErrorMessage() + ",未找到工号为" + workId + "的员工");
            }
            //更新员工
            Result<Boolean> updateResult = crPlatformEnhanceService.updateEmployee(UpdateEmployeeRequest.builder()
                    .id(employeeSDO.getId()).operatorId(employeeId).status(EmployeeStatusEnum.INVALID.getStatus()).build());
            if (!updateResult.isSuccess() || !updateResult.getResult()) {
                log.info("MnDataIf006:工号为" + workId + "的员工更新失败");
                return Result.success(false, "OTS-01-001-01-15-019", ErrorMessage.code("OTS-01-001-01-15-019", null).getDisplayErrorMessage() + ",工号为" + workId + "的员工更新失败");
            }
            String email = employeeSDO.getEmail();
            try {
                if (email != null) {
                    AccountDeactivationResponse response = bcOrderService.accountDeactivation(AccountDeactivationRequest.builder()
                            .email(email).build());
                    //邮件发送失败只记录
                    if (!response.getSuccess()) {
                        log.info("员工工号："+ workId + "邮件发送失败，原因：" + response.getMessage());
                    }
                }
            } catch (Exception e) {
                log.info("员工工号："+ workId + "邮件发送服务异常");
            }
            return Result.success(true);
        } catch (Exception e) {
            log.info("MnDataIf006:update服务异常");
            return Result.fail(false, "OTS-01-001-01-15-020", ErrorMessage.code("OTS-01-001-01-15-020", null).getDisplayErrorMessage());
        }
    }
}
